// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3) 
// Source File Name:   ApplicationClassLoader.java

package backstage.runtime;

import backstage.util.CodedClassLoader;
import java.io.*;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Iterator;
import java.util.Set;
import keel.resource.Archive;
import keel.resource.FileSystemSource;

public class ApplicationClassLoader extends CodedClassLoader
{

    public ApplicationClassLoader(String name)
    {
        super((backstage.runtime.ApplicationClassLoader.class).getClassLoader());
        appClassName = name;
    }

    public ApplicationClassLoader(ApplicationClassLoader loader)
    {
        super((backstage.runtime.ApplicationClassLoader.class).getClassLoader());
        appClassName = loader.appClassName;
        Object key;
        for(Iterator it = loader.getArchiveKeySet().iterator(); it.hasNext(); addArchive(key, loader.getArchive(key)))
            key = it.next();

    }

    public void openArchive(String path)
        throws IOException
    {
        Archive archive;
        if((new File(path)).equals(new File(".")))
            archive = new Archive(new FileSystemSource(path));
        else
            archive = Archive.openArchive(path);
        addArchive(path, archive);
    }

    public String getAppClassName()
    {
        return appClassName;
    }
    
    private Class defineClass(String name, byte buff[])
    {
        int index = name.lastIndexOf('.');
        if(index >= 0)
        {
            String pkgName = name.substring(0, index);
            Package pkg = getPackage(pkgName);
            if(pkg == null)
                definePackage(pkgName, null, null, null, null, null, null, null);
        }
        return defineClass(name, buff, 0, buff.length);
    }
    
    public final Class loadClass(String name, boolean resolve)
        throws ClassNotFoundException
    {
        Class clazz = findLoadedClass(name);
        if(clazz == null && (
        		name.startsWith("bmpviewer.") ||
        		name.startsWith("com.Acme.") ||
        		name.startsWith("com.cyberstep.") ||
        		name.startsWith("com.keypoint.") ||
        		name.startsWith("com.sdo.") ||
        		name.startsWith("com.wiselogic.") ||
        		//name.startsWith("javax.xml.parsers.") ||
        		//name.startsWith("javax.xml.transform.") ||
        		name.startsWith("kotori.") ||
        		name.startsWith("link.") 
        		//name.startsWith("org.apache.") ||
        		//name.startsWith("org.cybergarage.") ||
        		//name.startsWith("org.nanoxml.") ||
        		//name.startsWith("org.w3c.") ||
        		//name.startsWith("org.xml.")
        		))
        {       	
        	String path = name.replace('.', '/').concat(".class");
        	InputStream in = null;
        	if(getParent() != getSystemClassLoader())
        		in = getParent().getResourceAsStream(path);
        	if(in == null)
        		in = getSystemResourceAsStream(path);
        	
        	if(in != null)
        	{
        		ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        		int nRead;
        		byte[] data = new byte[2048];

        		try {
					while ((nRead = in.read(data)) != -1) {
					  buffer.write(data, 0, nRead);
					}
					buffer.flush();
					
					clazz = defineClass(name,buffer.toByteArray());
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
        	}
        }
        
        if(clazz == null)
            try
            {
                clazz = super.findClass(name);
            }
            catch(ClassNotFoundException e)
            {
                if(name.equals(appClassName))
                    throw new ClassNotFoundException(appClassName + " not found in entry class path");
                clazz = getParent().loadClass(name);
            }
        if(resolve)
            resolveClass(clazz);
        return clazz;
    }

    public void unloadLibrary()
    {
        try
        {
            super.finalize();
        }
        catch(Throwable t)
        {
            t.printStackTrace();
        }
    }

    protected void finalize()
        throws Throwable
    {
        super.finalize();
    }

    public static void startApplication(String className, String paths[], String args[])
    {
        className = className.replace('/', '.');
        ApplicationClassLoader classLoader = new ApplicationClassLoader(className);
        for(int i = 0; i < paths.length; i++)
        {
            String path = paths[i];
            try
            {
                classLoader.openArchive(path);
            }
            catch(IOException e)
            {
                System.err.println("Invalid archive path: " + path);
                e.printStackTrace();
            }
        }

        Thread.currentThread().setContextClassLoader(classLoader);
        try
        {
            Class entryClass = Class.forName(classLoader.getAppClassName(), true, classLoader);
            Method mainMethod = entryClass.getMethod("main", new Class[] {
                java.lang.String[].class
            });
            mainMethod.invoke(null, new Object[] {
                args
            });
        }
        catch(Exception e)
        {
            System.err.println("Exception in Application launching:");
            e.printStackTrace();
        }
    }

    private String appClassName;

    static 
    {
        AccessController.doPrivileged(new PrivilegedAction() {

            public Object run()
            {
                try
                {
                    System.loadLibrary("keel_clazz");
                }
                catch(UnsatisfiedLinkError e) { }
                return null;
            }

        }
);
    }
}
